package com.bawei.es.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bawei.domain.request.IndexInfoReq;
import com.bawei.domain.response.IndexInfoResp;
import com.bawei.es.service.EsIndexService;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.reindex.ReindexRequest;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
@Log4j2
public class EsIndexServiceImpl implements EsIndexService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 创建索引
     * @param indexInfoReq
     */
    @Override
    public  void createIndex(IndexInfoReq indexInfoReq){
        log.info("创建索引:{}", JSONObject.toJSONString(indexInfoReq));
        boolean exits = isExits(indexInfoReq.getIndexName());
        if(exits){
            throw new RuntimeException("索引"+indexInfoReq.getIndexName()+"已经存在");
        }
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexInfoReq.getIndexName());
        if(indexInfoReq.getIndexMapping()!=null){
            String mappingJson = JSONObject.toJSONString(indexInfoReq.getIndexMapping());
            createIndexRequest.mapping(mappingJson, XContentType.JSON);
        }
        try {
            restHighLevelClient.indices().create(createIndexRequest,RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    @Override
    public  boolean isExits(String indexName){
        //查询索引
        GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
        try {
            boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
            return exists;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 删除索引
     * @param indexName
     */
    @Override
    public  void deleteIndex(String indexName){
        boolean exits = isExits(indexName);
        if(exits){
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
            try {
                restHighLevelClient.indices().delete(deleteIndexRequest,RequestOptions.DEFAULT);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }else{
            throw  new RuntimeException("索引不存在");
        }
    }

    /**
     * 获取索引
     * @param indexName
     * @return
     */
    @Override
    public  IndexInfoResp getIndex(String indexName){
        boolean exits = isExits(indexName);
        if(exits){
            GetIndexRequest request = new GetIndexRequest(indexName);
           try {
               //构建返回对象
               IndexInfoResp indexInfoResp = new IndexInfoResp();
               GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
               //给返回对象赋值
               indexInfoResp.setIndexName(getIndexResponse.getIndices()[0]);
               indexInfoResp.setMappings(getIndexResponse.getMappings().get(indexName).getSourceAsMap());
               Settings settings = getIndexResponse.getSettings().get(indexName);
               Set<String> keySet = settings.keySet();
               Map<String, Object> mapSettings = new HashMap<>();
               keySet.forEach(key -> {
                   mapSettings.put(key,settings.get(key));
               });
               indexInfoResp.setSettings(mapSettings);
               Map<String, List<AliasMetadata>> aliases = getIndexResponse.getAliases();
               Map<String,Object> aliasesMap = JSONObject.parseObject(JSONObject.toJSONString(aliases), Map.class);
               indexInfoResp.setAliases(aliasesMap);
               return  indexInfoResp;
           }catch (Exception e){
               throw new RuntimeException(e);
           }
        }else{
            throw new RuntimeException("索引不存在");
        }

    }


    @Override
    public void modifyIndex(String newIndexName, IndexInfoReq indexInfoReq) {
        //创建新的索引
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(newIndexName);
        //判断有没有这个索引
        boolean exits = isExits(indexInfoReq.getIndexName());
        if(exits){
            try {
                //执行创建
                restHighLevelClient.indices().create(createIndexRequest,RequestOptions.DEFAULT);
            } catch (Exception e) {
                throw new RuntimeException("创建失败",e);
            }
            //把旧的索引中mapping数据更新到新的索引中
            createIndexRequest.mapping(indexInfoReq.getIndexMapping());

            //更新索引数据到新索引
            ReindexRequest reindrequest = new ReindexRequest();
            reindrequest.setSourceIndices(indexInfoReq.getIndexName());
            reindrequest.setDestIndex(newIndexName);
            try {
                restHighLevelClient.reindex(reindrequest,RequestOptions.DEFAULT);
            } catch (Exception e) {
                throw new RuntimeException("数据更新失败",e);
            }

            //删除旧的索引
            DeleteIndexRequest deleteIndex = new DeleteIndexRequest(indexInfoReq.getIndexName());
            try {
                restHighLevelClient.indices().delete(deleteIndex,RequestOptions.DEFAULT);
            } catch (IOException e) {
                throw new RuntimeException("删除索引失败"+e);
            }


        }
    }
    }

